[PATCH] rhi: vulkan: Fix unintentional SDR format selection
I needed to read back the swapchain image for my Vulkan RHI-enabled
QtQuick application, but it complained that
VK_FORMAT_A2R10G10B10_UNORM_PACK32 wasn't able to be read back - why?
My initial naive solution is to simply add it to the
swapchainReadbackTextureFormat function - but that wouldn't work as
there is no BGR10A2 RHI texture format and applications would unkowingly
end up with swapped channels. The actual problem came down to how we
were selecting swapchain image formats.
The first thing I changed was the hdrFormatMatchesVkSurfaceFormat
function, because that checked two formats for HDR10:
VK_FORMAT_A2B10G10R10_UNORM_PACK32 and
VK_FORMAT_A2R10G10B10_UNORM_PACK32. Checking the online Vulkan hardware
database, the BGR variant is more well-supported. Picking the RGB
variant is inevitably going to lead into the problem described before -
and should be added back when & if a new RHI texture format is
introduced.
The next thing I changed was the swapchain format selection logic,
specifically the choice for a non-sRGB SDR format. Judging by the
comments in this function and other RHIs like DX12 we *want* the default
color format of VK_FORMAT_B8G8R8A8_UNORM unless otherwise requested.
That isn't what was happening though, on my specific hardware it was
choosing VK_FORMAT_A2R10G10B10_UNORM_PACK32 - why?
It comes down to the isSrgbFormat check in the loop. Again, for the
non-SRGB SDR case the "srgbRequested" variable is always false. And when
a non-SRGB format (like the aforementioned problematic VkFormat) is
checked isSrgbFormat will return false, but I don't think that's what is
intended here. We want that for the sRGB case, but for non-SRGB SDR the
default color format is fine and that lines up with other RHIs
(see QD3D12SwapChain::chooseFormats for an example.) I checked this
inside the loop so the passthrough code is still ran on Wayland, but I
think the new logic is still sensible.
I tested this against the five usual cases I could think of and now the
format selection seems sensible:
* non-sRGB SDR chose VK_FORMAT_B8G8R8A8_UNORM
* sRGB SDR chose VK_FORMAT_R8G8B8A8_SRGB
* extended sRGB Linear chose VK_FORMAT_R16G16B16A16_SFLOAT
* HDR10 chose VK_FORMAT_A2B10G10R10_UNORM_PACK32
* Display P3 chose VK_FORMAT_R16G16B16A16_SFLOAT
Change-Id: Ie79e9fcaa1130311958b485af9b73c59d5d9a335
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
(cherry picked from commit
2dd1aa3678d541aef15b564b4013728ed5b0387b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit
f4c5e54a8703944ec7ea005ad4de3072b86fd61f)
Gbp-Pq: Name upstream_hdr_vulkan.diff